package cn.changeforyou.common.logFramework.logback.rolling;

import ch.qos.logback.classic.spi.LoggingEvent;
import ch.qos.logback.core.util.FileSize;
import cn.changeforyou.common.logFramework.logback.rolling.SizeAndTimeBasedFNATP.Usage;
import cn.changeforyou.common.logFramework.logback.rolling.helper.SignLogUtil;
import java.io.File;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class SignFileAndSizeAndTimeBasedRollingPolicy<E> extends TimeBasedRollingPolicy<E> implements SignFileChangePolicy {

      FileSize maxFileSize;

      private Map<String, File> activeFiles = new ConcurrentHashMap<>();

      static final String SP = "_";

      @Override
      public void start() {
            SizeAndTimeBasedFNATP<E> sizeAndTimeBasedFNATP = new SizeAndTimeBasedFNATP<E>(Usage.EMBEDDED);
            if (maxFileSize == null) {
                  addError("maxFileSize property is mandatory.");
                  return;
            } else {
                  addInfo("Archive files will be limited to [" + maxFileSize + "] each.");
            }

            sizeAndTimeBasedFNATP.setMaxFileSize(maxFileSize);
            timeBasedFileNamingAndTriggeringPolicy = sizeAndTimeBasedFNATP;

            if (!isUnboundedTotalSizeCap() && totalSizeCap.getSize() < maxFileSize.getSize()) {
                  addError("totalSizeCap of [" + totalSizeCap + "] is smaller than maxFileSize [" + maxFileSize + "] which is non-sensical");
                  return;
            }

            // most work is done by the parent
            super.start();
      }


      public void setMaxFileSize(FileSize aMaxFileSize) {
            this.maxFileSize = aMaxFileSize;
      }

      @Override
      public String getActiveFileName() {
            String parentsRawFileProperty = getParentsRawFileProperty();
            if (parentsRawFileProperty != null) {
                  return parentsRawFileProperty;
            } else {
                  return timeBasedFileNamingAndTriggeringPolicy.getCurrentPeriodsFileNameWithoutCompressionSuffix();
            }
      }


      @Override
      public String toString() {
            return "c.q.l.core.rolling.SizeAndTimeBasedRollingPolicy@" + this.hashCode();
      }

      @Override
      public String getSignFileNameByEvent(LoggingEvent event) {
            if (event instanceof LoggingEvent) {
                  LoggingEvent e = (LoggingEvent) event;
                  String message = e.getMessage();
                  String activeFileName = getActiveFileName();
                  return SignLogUtil.getSignFromSignLogString(message);
            }
            return null;
      }

      @Override
      public boolean isChangeSignFile(File currentlyActiveFile, String sign) {
            String activeFileName = getActiveFileName();
            int index = activeFileName.lastIndexOf("/");
            if (index == -1) {
                  if (currentlyActiveFile.getName().startsWith(sign + SP)) {
                        return false;
                  }else {
                        return true;
                  }
            }else {
                  if (activeFileName.substring(index + 1).startsWith(sign + SP)) {
                        return false;
                  }else {
                        return true;
                  }
            }
      }

      @Override
      public String getFileNameBySign(String sign) {
            String activeFileName = getActiveFileName();
            int index = activeFileName.lastIndexOf("/");
            if (index == -1) {
                  return sign + SP + activeFileName;
            }else {
                  return activeFileName.substring(0, index + 1) +  sign + SP + activeFileName.substring(index + 1);
            }

      }
}
